package org.grill.fatwhacker.gui;

import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ControlEditor;
import org.eclipse.swt.custom.TableCursor;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.grill.fatwhacker.data.DailyRecord;
import org.grill.fatwhacker.data.FoodEntry;

public class DayItemTableView {
	private boolean isFood;

	public DayItemTableView(final Composite parentComposite, boolean isFood) {
		this.isFood = isFood;
		groupComposite = new Composite(parentComposite, SWT.NONE);
		GridLayout layout = new GridLayout(SWT.NONE, false);
		layout.numColumns = 1;
		layout.marginWidth = 8;
		
		groupComposite.addPaintListener(getPaintListener());
		
		groupComposite.setLayout(layout);
		
		new Label(groupComposite, SWT.LEFT).setText(isFood ? "Food" : "Exercise");
		
		itemTable = new Table(groupComposite, SWT.MULTI);
		GridData tableData = new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		itemTable.setLayoutData(tableData);
		
		TableColumn itemCol = new TableColumn(itemTable, SWT.NONE);
		itemCol.setText("Item");
		itemCol.setWidth(150);
		
		TableColumn valueCol = new TableColumn(itemTable, SWT.NONE);
		valueCol.setText("Value");
		valueCol.setWidth(50);
		
		
		itemTable.setHeaderVisible(true);
		
		final TableCursor cursor = new TableCursor(itemTable, SWT.NONE);
		final ControlEditor editor = new ControlEditor(cursor);
		cursor.addKeyListener(new KeyListener() {
		
			public void keyReleased(KeyEvent arg0) {
				// TODO Auto-generated method stub
		
			}
		
			public void keyPressed(KeyEvent arg0) {
				if ((arg0.keyCode == SWT.ARROW_LEFT) || (arg0.keyCode == SWT.ARROW_RIGHT) || 
						(arg0.keyCode == SWT.ARROW_UP)  || (arg0.keyCode == SWT.ARROW_DOWN) || 
						(arg0.keyCode == SWT.ALT) || (arg0.keyCode == SWT.CONTROL) || (arg0.keyCode == SWT.COMMAND) || (arg0.keyCode == SWT.SHIFT))
					return;
					
				if (arg0.keyCode == SWT.DEL || arg0.keyCode == SWT.BS) {
					handleDeletion();
					return;
				}
				setupEditor(cursor, editor);
		
			}
		
		});
		
		cursor.addListener(SWT.MouseDown, new Listener() {
			public void handleEvent(Event arg0) {
				setupEditor(cursor, editor);
				if (currentEditControl instanceof Text) {
					Text t = (Text)currentEditControl;
					t.setSelection(t.toControl(parentComposite.getDisplay().getCursorLocation()));
				}
				
			}
		});
		

		
		
		editor.grabHorizontal = true;
		editor.grabVertical = true;
	}
	
	private PaintListener getPaintListener() {
		return new PaintListener() {
			public void paintControl(PaintEvent e) {
				Point size = groupComposite.getSize();
//				e.gc.drawRoundRectangle(2, 2, size.x-5, size.y-5, 5, 5);
			}
		};
	}

	protected void handleDeletion() {
		MessageBox mb = new MessageBox(itemTable.getShell(), SWT.YES | SWT.NO);
		mb.setText("Delete?");
		mb.setMessage("Really delete this item?");
		if (mb.open() == SWT.NO)
			return;
		
		int selectionIndex = itemTable.getSelectionIndex();
		if (selectionIndex == -1 ) return;
		
		TableItem item = itemTable.getItem(selectionIndex);
		FoodEntry entry = (FoodEntry) item.getData();
		
		if (entry == null) return;
		
		currentDay.getEntries().remove(entry);
		item.dispose();
		notifyListeners();
	}

	public void render() {
		if (currentDay == null)
			return;
		
		itemTable.removeAll();
		
		for (FoodEntry entry : currentDay) {
			if (entry.isFood() != isFood)
				continue;
			
			TableItem item = new TableItem(itemTable, SWT.NONE);
			item.setText(0, entry.getName());
			item.setText(1, String.valueOf((int)entry.getValue()));
			item.setData(entry);
		}
		TableItem empty = new TableItem(itemTable, SWT.NONE);
		empty.setText(new String[] {"","", "Food"});
	}
	
	public void fireChanged() {
		System.out.println("FireChnaged called");
		int selectionIndex = itemTable.getSelectionIndex();
		if (selectionIndex == -1 ) return;
		
		TableItem item = itemTable.getItem(selectionIndex);
		FoodEntry entry = (FoodEntry) item.getData();
		if (entry == null) {
			entry = new FoodEntry();
			item.setData(entry);
			entry.setFood(isFood);
			currentDay.getEntries().add(entry);
			new TableItem(itemTable, SWT.NONE);
		}
		entry.setName(item.getText(0));
		try {
			entry.setValue(Float.parseFloat(item.getText(1)));
		} catch (IllegalArgumentException e) {};
		
	    
	    
//	    currentDay.dump();
	    
	    notifyListeners();
	}

	private void notifyListeners() {
		for (Listener listener : listeners) {
	    	listener.handleEvent(new Event());
	    }
	}
	
	public void addChangeListener(Listener l) {
		listeners.add(l);
	}
	
	private ArrayList<Listener> listeners = new ArrayList<Listener>();
	
	private DailyRecord currentDay;
	private Table itemTable;
	
	public void setDay(DailyRecord current)
	{
		currentDay = current;
	}
	
	private Control currentEditControl = null;

	private Composite groupComposite;

	private void setupEditor(final TableCursor cursor, final ControlEditor editor) {
		TableItem row = cursor.getRow();
		if (row == null) return;
		int column = cursor.getColumn();

		String currText = row.getText(column);

		final Text text = new Text(cursor, SWT.NONE);
		currentEditControl = text;


		text.setText(currText);
		text.selectAll();
		text.addTraverseListener(new TraverseListener() {
		
			public void keyTraversed(TraverseEvent arg0) {
				System.out.println("Traversal: " + arg0);
				if (arg0.keyCode == SWT.TAB)
					arg0.doit = false;
			}
		
		});
		text.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				// close the text editor and copy the data over 
				// when the user hits "ENTER"
				if (e.character == SWT.CR || e.character == SWT.TAB) {
					TableItem row = cursor.getRow();
					int column = cursor.getColumn();
					row.setText(column, text.getText());
					fireChanged();
					text.dispose();
					if (column == 1) {
						itemTable.setSelection(itemTable.indexOf(row)+1);
						cursor.setSelection(itemTable.indexOf(row)+1, 0);
					} else {
						cursor.setSelection(itemTable.indexOf(row), column + 1);
					}
					cursor.setFocus();
				}
				// close the text editor when the user hits "ESC"
				if (e.character == SWT.ESC) {
					text.dispose();
					cursor.setFocus();
				}
			}

			public void keyReleased(KeyEvent arg0) {
				// TODO Auto-generated method stub

			}
		});
		currentEditControl.addFocusListener(new FocusListener() {

			public void focusLost(FocusEvent arg0) {
				TableItem row = cursor.getRow();
				int column = cursor.getColumn();
				row.setText(column, text.getText());
				fireChanged();
				currentEditControl.dispose();
			}

			public void focusGained(FocusEvent arg0) {
				// TODO Auto-generated method stub

			}

		});


		currentEditControl.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent arg0) {
				currentEditControl = null;
			}
		});

		editor.setEditor(currentEditControl);
		currentEditControl.setFocus();
	}
}
